/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: LogAop
 * Author:   sky
 * Date:     2020/5/9 22:53
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package cn.szh.controller;

import cn.szh.domain.SysLog;
import cn.szh.service.SysLogService;
import cn.szh.utils.DateUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import sun.plugin.liveconnect.SecurityContextHelper;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;


/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author sky
 * @create 2020/5/9
 * @since 1.0.0
 */
@Component
@Aspect
public class LogAop {
//    private int id;
//    private Date visitTime;
//    private String visitTimeStr;
//    private String username;
//    private String ip;
//    private String url;
//    private Long executionTime;
//    private String method;
    private Date startTime;
    private Class TargetClass;
    private Method TargetMethod;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SysLogService sysLogService;
    //获取访问时间，类名，方法，参数
    @Before("execution(* cn.szh.controller.*.*(..))")
    public void doBefore(JoinPoint joinPoint ) throws NoSuchMethodException {
        startTime=new Date();
        //获取访问的类
        TargetClass= joinPoint.getTarget().getClass();
        //获取访问的方法
        String methodname = joinPoint.getSignature().getName();
        //获取参数
        Object[] args = joinPoint.getArgs();
        if (args==null||args.length==0){
            TargetMethod = TargetClass.getMethod(methodname);
        }else {
            // 有参数，就将args中所有元素遍历，获取对应的Class类型,装入到一个Class[]
            Class[] classArgs = new Class[args.length];
            for (int i=0;i<args.length;i++){
                //获取参数的类型
                classArgs[i]=args[i].getClass();
            }
            TargetMethod = TargetClass.getMethod(methodname, classArgs);
        }
    }
    // 主要获取日志中其它信息，时长、ip、url
    @After("execution(* cn.szh.controller.*.*(..))")
    public void doAfter(JoinPoint joinPoint){



        if (TargetClass!=null&&TargetMethod!=null&&TargetClass!=LogAop.class) {
            RequestMapping classAnnotation = (RequestMapping) TargetClass.getAnnotation(RequestMapping.class);
            if (classAnnotation != null){
                RequestMapping methodAnnotation = (RequestMapping) TargetMethod.getAnnotation(RequestMapping.class);
              if (methodAnnotation!=null) {
                  String url = classAnnotation.value()[0] + methodAnnotation.value()[0];
                  String remoteAddr = request.getRemoteAddr();
                  long executionTime = new Date().getTime() - startTime.getTime();
                  SecurityContext context = SecurityContextHolder.getContext();
                  User user = (User) context.getAuthentication().getPrincipal();
                  String username = user.getUsername();
                  SysLog sysLog=new SysLog();
                  sysLog.setIp(remoteAddr);
                  sysLog.setExecutionTime(executionTime);
                  sysLog.setMethod("[类名] "+TargetClass.getName()+"[方法名] "+TargetMethod.getName());
                  sysLog.setUsername(username);
                  sysLog.setUrl(url);
                  sysLog.setVisitTimeStr(DateUtils.date2String(startTime,"yyyy-MM-dd hh:mm:ss"));
                  sysLog.setVisitTime(startTime);
                  sysLogService.save(sysLog);
              }
          }
        }

    }

}
